package org.jeecg.modules.strategy.component;

import cn.hutool.core.lang.UUID;
import org.apache.commons.lang.StringUtils;
import org.jeecg.modules.strategy.model.entity.MetaEntity;
import org.jeecg.modules.strategy.util.SpiderUtil;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Component
public class MetaPageProcessor implements PageProcessor {
    @Override
    public Site getSite() {
        return Site.me()
                .setRetryTimes(1)
                .setSleepTime(1000)
                .setTimeOut(10000)
                .setCharset(StandardCharsets
                        .UTF_8.name());
    }

    @Override
    public void process(Page page) {
        Html html = page.getHtml();
        List<String> metaAll = html.$("head > meta").all();
        if (!metaAll.isEmpty()){
            metaAll.remove(0);
            ArrayList<String> metaNameAll = new ArrayList<>();
            MetaEntity metaEntity = new MetaEntity();
            metaAll.forEach(meta -> {
                String metaName = getMetaName(meta, metaNameAll);
                String contentTest = new SpiderUtil().getContentTest(meta);
                metaEntitySetContent(metaName, metaEntity, contentTest);
            });
            if (metaEntity.getSiteDomain() != null && metaEntity.getSiteIdCode() != null && metaEntity.getSiteName() != null) {
                metaEntity.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                metaEntity.setUrl(page.getUrl().toString());
                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                metaEntity.setCreateTime(time);
                metaEntity.setUpdateTime(time);
                metaEntity.setIsDelete(0);
                page.putField("metaEntity", metaEntity);
            }
            List<String> urlAll = getUrlAll(page, metaNameAll, html);
            if (!urlAll.isEmpty())
                page.addTargetRequests(urlAll);
        }
    }

    private String getMetaName(String meta, ArrayList<String> metaNameAll) {
        int nameSubstringStart = meta.indexOf("name=\"") + "name=\"".length() ;
        int nameSubstringEnd = meta.indexOf("\"", nameSubstringStart + 1);
        String nameTest = meta.substring(nameSubstringStart, nameSubstringEnd);
        if (nameTest.charAt(0) == '“' || nameTest.charAt(0) == '\'')
            nameTest = meta.substring(nameSubstringStart + 1, meta.indexOf("”"));
        metaNameAll.add(nameTest);
        return nameTest;
    }

    private static List<String> getUrlAll(Page page, ArrayList<String> metaNameAll, Html html) {
        List<String> urlAll = new ArrayList<>();
        metaNameAll.forEach(metaName -> {
            if (
                    !(metaName.equals("ArticleTitle")
                            || metaName.equals("articleTitle")
                            || metaName.equals("Articletitle")
                            || metaName.equals("articletitle")
                            || metaName.equals("Article_Title")
                            || metaName.equals("article_Title")
                            || metaName.equals("Article_title")
                            || metaName.equals("article_title")
                            || metaName.equals("Article-Title")
                            || metaName.equals("article-Title")
                            || metaName.equals("Article-title")
                            || metaName.equals("article-title")
                    )
            ) {
                List<String> linkAll = html.links().all();
                if (!linkAll.isEmpty()) {
                    linkAll.forEach(link -> {
                        String newLink = link.replaceAll("http://", "https://");
                        String[] urlSplit = page.getUrl().toString().replaceAll("http://", "").replaceAll("https://", "").split("/");
                        String[] linkSplit = newLink.replaceAll("http://", "").replaceAll("https://", "").split("/");
                        if (urlSplit[0].equals(linkSplit[0])) {
                            urlAll.add(newLink);
                        }
                    });
                }
            }
        });
        return urlAll;
    }

    private static void metaEntitySetContent(String metaName, MetaEntity metaEntity, String contentTest) {
        if (StringUtils.isEmpty(metaName))
            return;
        switch (metaName) {
            case "SiteName":
            case "siteName":
            case "Sitename":
            case "sitename":
            case "Site_Name":
            case "site_Name":
            case "Site_name":
            case "site_name":
            case "Site-Name":
            case "site-Name":
            case "Site-name":
            case "site-name":
                metaEntity.setSiteName(contentTest);
                break;
            case "SiteDomain":
            case "siteDomain":
            case "sitedomain":
            case "siteDoMain":
            case "sitedoMain":
            case "SiteDoMain":
            case "SitedoMain":
            case "Site-Domain":
            case "site-Domain":
            case "site-domain":
            case "site-DoMain":
            case "site-doMain":
            case "Site-DoMain":
            case "Site-doMain":
            case "SiteDo-main":
            case "siteDo-main":
            case "sitedo-main":
            case "siteDo-Main":
            case "sitedo-Main":
            case "SiteDo-Main":
            case "Sitedo-Main":
            case "Site-Do-main":
            case "site-Do-main":
            case "site-do-main":
            case "site-Do-Main":
            case "site-do-Main":
            case "Site-Do-Main":
            case "Site-do-Main":
            case "Site_Domain":
            case "site_Domain":
            case "site_domain":
            case "site_DoMain":
            case "site_doMain":
            case "Site_DoMain":
            case "Site_doMain":
            case "SiteDo_main":
            case "siteDo_main":
            case "sitedo_main":
            case "siteDo_Main":
            case "sitedo_Main":
            case "SiteDo_Main":
            case "Sitedo_Main":
            case "Site_Do_main":
            case "site_Do_main":
            case "site_do_main":
            case "site_Do_Main":
            case "site_do_Main":
            case "Site_Do_Main":
            case "Site_do_Main":
            case "Site-Do_main":
            case "site-Do_main":
            case "site-do_main":
            case "site-Do_Main":
            case "site-do_Main":
            case "Site-Do_Main":
            case "Site-do_Main":
            case "Site_Do-main":
            case "site_Do-main":
            case "site_do-main":
            case "site_Do-Main":
            case "site_do-Main":
            case "Site_Do-Main":
            case "Site_do-Main":
                metaEntity.setSiteDomain(contentTest);
                break;
            case "SiteIDCode":
            case "SiteiDCode":
            case "SiteIdCode":
            case "SiteIDcode":
            case "siteIDCode":
            case "siteiDCode":
            case "siteIdCode":
            case "siteIDcode":
            case "siteiDcode":
            case "siteidcode":
            case "Site_IDCode":
            case "Site_iDCode":
            case "Site_IdCode":
            case "Site_IDcode":
            case "site_IDCode":
            case "site_iDCode":
            case "site_IdCode":
            case "site_IDcode":
            case "site_iDcode":
            case "site_idcode":
            case "SiteID_Code":
            case "SiteiD_Code":
            case "SiteId_Code":
            case "SiteID_code":
            case "siteID_Code":
            case "siteiD_Code":
            case "siteId_Code":
            case "siteID_code":
            case "siteiD_code":
            case "siteid_code":
            case "Site_ID_Code":
            case "Site_iD_Code":
            case "Site_Id_Code":
            case "Site_ID_code":
            case "site_ID_Code":
            case "site_iD_Code":
            case "site_Id_Code":
            case "site_ID_code":
            case "site_iD_code":
            case "site_id_code":
            case "Site-IDCode":
            case "Site-iDCode":
            case "Site-IdCode":
            case "Site-IDcode":
            case "site-IDCode":
            case "site-iDCode":
            case "site-IdCode":
            case "site-IDcode":
            case "site-iDcode":
            case "site-idcode":
            case "SiteID-Code":
            case "SiteiD-Code":
            case "SiteId-Code":
            case "SiteID-code":
            case "siteID-Code":
            case "siteiD-Code":
            case "siteId-Code":
            case "siteID-code":
            case "siteiD-code":
            case "siteid-code":
            case "Site-ID_Code":
            case "Site-iD_Code":
            case "Site-Id_Code":
            case "Site-ID_code":
            case "site-ID-Code":
            case "site-iD-Code":
            case "site-Id-Code":
            case "site-ID-code":
            case "site-iD-code":
            case "site-id-code":
            case "Site-ID-Code":
            case "Site-iD-Code":
            case "Site-Id-Code":
            case "Site-ID-code":
            case "site-ID_Code":
            case "site-iD_Code":
            case "site-Id_Code":
            case "site-ID_code":
            case "site-iD_code":
            case "site-id_code":
            case "Site_ID-Code":
            case "Site_iD-Code":
            case "Site_Id-Code":
            case "Site_ID-code":
            case "site_ID-Code":
            case "site_iD-Code":
            case "site_Id-Code":
            case "site_ID-code":
            case "site_iD-code":
            case "site_id-code":
                metaEntity.setSiteIdCode(contentTest);
                break;
            case "CopyRight":
            case "copyRight":
            case "Copyright":
            case "copyright":
            case "Copy_Right":
            case "copy_Right":
            case "Copy_right":
            case "copy_right":
            case "Copy-Right":
            case "copy-Right":
            case "Copy-right":
            case "copy-right":
                metaEntity.setCopyright(contentTest);
                break;
            case "RevisitAfter":
            case "revisitAfter":
            case "Revisitafter":
            case "revisitafter":
            case "Revisit_After":
            case "revisit_After":
            case "Revisit_after":
            case "revisit_after":
            case "Revisit-After":
            case "revisit-After":
            case "Revisit-after":
            case "revisit-after":
                metaEntity.setRevisitAfter(contentTest);
                break;
            case "ColumnName":
            case "columnName":
            case "Columnname":
            case "columnname":
            case "Column_Name":
            case "column_Name":
            case "Column_name":
            case "column_name":
            case "Column-Name":
            case "column-Name":
            case "Column-name":
            case "column-name":
                metaEntity.setColumnName(contentTest);
                break;
            case "ColumnType":
            case "columnType":
            case "Columntype":
            case "columntype":
            case "Column_Type":
            case "column_Type":
            case "Column_type":
            case "column_type":
            case "Column-Type":
            case "column-Type":
            case "Column-type":
            case "column-type":
                metaEntity.setColumnType(contentTest);
                break;
            case "ColumnDescription":
            case "columnDescription":
            case "Columndescription":
            case "columndescription":
            case "Column_Description":
            case "column_Description":
            case "Column_description":
            case "column_description":
            case "Column-Description":
            case "column-Description":
            case "Column-description":
            case "column-description":
                metaEntity.setColumnDescription(contentTest);
                break;
            case "ColumnKeywords":
            case "columnKeywords":
            case "Columnkeywords":
            case "columnkeywords":
            case "Column_Keywords":
            case "column_Keywords":
            case "Column_keywords":
            case "column_keywords":
            case "Column-Keywords":
            case "column-Keywords":
            case "Column-keywords":
            case "column-keywords":
                metaEntity.setColumnKeywords(contentTest);
                break;
            case "ArticleTitle":
            case "articleTitle":
            case "Articletitle":
            case "articletitle":
            case "Article_Title":
            case "article_Title":
            case "Article_title":
            case "article_title":
            case "Article-Title":
            case "article-Title":
            case "Article-title":
            case "article-title":
                metaEntity.setArticleTitle(contentTest);
                break;
            case "PubDate":
            case "pubDate":
            case "Pubdate":
            case "pubdate":
            case "Pub_Date":
            case "pub_Date":
            case "Pub_date":
            case "pub_date":
            case "Pub-Date":
            case "pub-Date":
            case "Pub-date":
            case "pub-date":
                metaEntity.setPubDate(contentTest);
                break;
            case "ContentSource":
            case "contentSource":
            case "Contentsource":
            case "contentsource":
            case "Content_Source":
            case "content_Source":
            case "Content_source":
            case "content_source":
            case "Content-Source":
            case "content-Source":
            case "Content-source":
            case "content-source":
                metaEntity.setContentSource(contentTest);
                break;
            case "KeyWords":
            case "keyWords":
            case "Keywords":
            case "keywords":
            case "Key_Words":
            case "key_Words":
            case "Key_words":
            case "key_words":
            case "Key-Words":
            case "key-Words":
            case "Key-words":
            case "key-words":
                metaEntity.setKeywords(contentTest);
                break;
            case "Author":
            case "author":
                metaEntity.setAuthor(contentTest);
                break;
            case "Description":
            case "description":
                metaEntity.setDescription(contentTest);
                break;
        }
    }
}
